System Design_大型网站高性能架构

网站性能测试

性能测试指标

  • 响应时间:指应用执行一个请求到相应所需要的时间。
  • 并发数:只系统同时处理请求的数目,最大并发数数值也反映了系统的负载特性。
  • 吞吐量(TPS):指单位时间内系统处理的请求量,体现系统的整体处理能力。在系统并发数由小增大的过程中,系统吞吐量先是逐渐增加,达到一个极限后,随着并发数的增加反而下降,达到系统崩溃点后,系统资源耗尽,吞吐量为0。可以理解为吞吐量是每天通过收费站的车辆数目,并发数是高速公路上的车辆数目。
  • 性能计数器:描述服务器或者操作系统性能的一些数据指标,如System loab, 内存使用,CPU使用..

性能测试方法

  • 性能测试:对系统不断施加压力,验证系统在资源可接受范围内,能否达到性能预期。
  • 负载测试:对系统不断增加并发请求以增加系统压力,直到系统的某项或者性能指标达到安全临界值,如果某种资源已经是饱和状态,这时继续提高压力,系统的吞出量不但不能提高,反而会下降。
  • 压力测试:超过安全负载的情况下,对系统继续施加压力,直到系统崩溃或者不能再处理任何请求,以此获得系统最大压力承受能力。
  • 稳定性测试:在特定硬件、软件、网络环境下,给系统加载一定业务压力,是系统运行一段较长时间,以测试是否稳定。

上面的的增加压力,就是不断增加并发请求数,消耗的系统资源也会变多。

System_design_c4_2

System_design_c4_1

性能测试报告

测试结果报告应该能反映上述性能测试曲线的规律,阅读者可以得到系统性能是否满足设计目标和业务要求、系统最大负载能力、系统最大压力承受能力等重要信息。

System_design_c4_3

性能优化策略

检查请求处理的各个环节的日志,分析哪个环节响应时间不合理;然后检查监控数据,分析影响性能的主要因素是内存、磁盘、网络还是CPU,是代码或架构问题或者是系统资源确实不足。

定位具体原因后,根据具体层次进行优化。

Web前端性能优化

Web前端一般指业务逻辑之前的部分,包括浏览器加载、网站视图模型、图片服务、CDN服务等,主要优化手段有优化浏览器、使用反向代理、CDN等。

浏览器访问优化

  1. 减少HTTP请求,因为每次都要开启线程建立通信链路。如合并CSS, Javascript等。
  2. 使用浏览器缓存。
  3. 启用压缩
  4. 减少Cookie传输

CDN加速

CDN(Content Distribute Network,内容分发网络)的本质仍是一个缓存,将数据缓存在离用户最近的地方。

CDN能偶缓存的一般是静态资源,如图片,文件,视频等。

System_design_c4_4

反向代理

传统代理服务器位于浏览器一侧,代理浏览器将HTTP请求发送到互联网上,而反向代理服务器位于网站机房一侧,代理网站Web服务器接收HTTP请求。

System_design_c4_5

和传统代理服务器可以保护浏览器安全一样,反向代理服务器也具有保护网站安全的作用,来自互联网的访问必须经过反向代理服务器。

除了安全功能,代理服务器也可以通过配置缓存功能加速Web请求。

此外,反向代理还可以实现负载均衡的功能,通过构建负载均衡的应用集群可以提高系统的总体处理能力,进而改善网站高并发下的性能。

应用服务器性能优化

应用服务器就是处理网站业务的服务器,网站的业务代码都部署在这里,是网站开发最复杂、变化最多的地方,主要优化手段有缓存、集群、异步等。

分布式缓存

任何时候,优先考虑使用缓存优化性能。

缓存基本原理

缓存指将数据存储在相对较高访问速度的存储介质中,一方面可以减少访问时间,同时也可能减少计算时间。缓存的本质是一个内存Hash表,网站应用中,数据缓存以一对Key、Value的形式存储在内存Hash表中。

System_design_c4_7

缓存主要用来存放读写比例很高、变化很少的数据,即80%的访问在20%的数据上。通过缓存可以提高数据读取速度,降低存储访问压力。

合理使用缓存

几个要注意的问题:
频发修改的数据
没有热点的访问
数据不一致与脏读
缓存可用性:数据库可能在缓存服务崩溃时由于承受突然增加的压力而宕机,进而导致整个网站不可用,称为缓存雪崩。分布式缓存可以在一定程度上改善缓存的可用性。
缓存预热:在启动缓存后,可能需要较长时间重建缓存数据,可以在缓存系统启动时就准备好热点数据然后直接加载。例如,一些元数据可以全部加载。
缓存穿透:如果因为不恰当的业务、或者恶意攻击持续高并发地请求某个不存在的数据,由于缓存没有保存该数据,所有的请求的都会落到数据库上,会对数据库造成很大的压力。一个简单的对策是将这些不存在的数据也缓存起来,value值设置为null。

分布式缓存架构

分布式缓存指缓存部署在多个服务器组成的集群中,以集群方式提供缓存服务,其架构方式有两种,一种是以JBoss Cache为代表的需要更新同步的分布式缓存,一种是以Memcached为代表的不互相通信的分布式缓存。

JBoss Cache的分布式缓存在集群中所有的服务器中保存相同的缓存数据,当某台服务器有缓存数据更新时,会通知集群中其他机器更新。当集群规模较大时,同步代价非常大,且由于多台服务器存有多份相同的数据,内存利用率不高。

System_design_c4_8

Memcached

Memcached采用一种集中式的缓存集群管理,也就是互不通信的分布式架构模式,缓存与应用分离部署,部署在一组专门的服务器上,应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据,缓存服务器之间不通信,可以很容易的实现扩容,具有良好的可伸缩性。

System_design_c4_9

简单的通信协议
高性能的网络通信
高效的内存管理
Memcached使用了固定空间分配。将内存空间分为一组Slab,每个slab里又包含一组chunk,同一个slab里的每个chunck的大小是固定的,拥有相同大小chunk的slab被组织在一起,称为slab_class。

System_design_c4_10

互不通信的服务器集群架构:正是这个架构使得集群可以做到几乎无限制的线性伸缩。

异步操作

使用消息队列将调用异步化,可以改善网站的扩展性。同时还可以改善网站系统的性能。

System_design_c4_11

在不使用消息队列的情况下,用户的请求数据直接写入数据库,在高并发的情况下,会对数据库造成巨大的压力,同时也使得相应延迟加剧。使用消息队列后,用户请求在被发送给消息队列后立即返回,响应延迟可以得到有效改善,再由消息队列的合适数量的消费者进程进行处理,进行数据库读写,不必创建超过负载的处理进程。

消息队列具有很好的削峰作用—即通过异步处理,将段时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。在电子商务网站促销活动中,合理使用消息队列可以有效抵御冲击。

System_design_c4_12

使用集群

在网站高并发访问场景下,使用负载均衡计数为一个应用构建由多台服务器组成的服务器集群,将并发访问请求分发到多台服务器上处理,避免单一服务器因负载压力过大而响应缓慢,是用户请求具有更好的响应延迟特性。

System_design_c4_13

代码优化

  • 多线程
    假设服务器执行都是相同类型服务,估算公式:
    启动线程数=[任务执行时间/(任务执行时间-IO等待时间)] * CPU内核数
    需要注意线程安全问题。
  • 资源复用
    减少开销大的系统资源创建和销毁,使用单例模式和对象池,线程池。
  • 数据结构和高效算法
  • 垃圾回收
    如在JVM情况下,合理设置Young Generation和Old Generation大小,尽量减少Full GC。根据应用设置合理的回收模式。

存储性能优化

机械硬盘 vs 固体硬盘

B+树 vs LSM树

RAID vs HDFS